/*
 * Copyright (C) 2016 david.wei (lighters)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.one.common.model.http.proxy;

import android.util.Log;

import com.one.common.utils.Logger;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Date;

import io.reactivex.Observable;

/**
 * Created by david on 16/8/21.
 * Email: huangdiv5@gmail.com
 * GitHub: https://github.com/alighters
 */
public class ProxyHandler implements InvocationHandler {

    private final static String TAG = "Token_Proxy";

    private final static String SESSION_ID = "session_id";

    private final static int REFRESH_TOKEN_VALID_TIME = 30;
    private static long tokenChangedTime = 0;
    private Throwable mRefreshTokenError = null;
    private boolean mIsTokenNeedRefresh;

    private Object mProxyObject;

    public ProxyHandler(Object proxyObject) {
        mProxyObject = proxyObject;
    }

    @Override
    public Object invoke(final Object proxy, final Method method, final Object[] args) {
        try {
            Logger.d("retrofit  代理 " + args.toString());
            return method.invoke(mProxyObject, args);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }


//        return Observable.just("").flatMap(new Function<Object, ObservableSource<?>>() {
//            @Override
//            public ObservableSource<?> apply(@NonNull Object o) throws Exception {
//                try {
////                        if (mIsTokenNeedRefresh) {
////                            updateMethodToken(method, args);
////                        }
//                        return (Observable<?>) method.invoke(mProxyObject, args);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//                return null;
//            }
//        }).retryWhen(new Function<Observable<? extends Throwable>, ObservableSource<?>>() {
//            @Override
//            public ObservableSource<?> apply(@NonNull final Observable<? extends Throwable> observable) throws Exception {
//                return observable.flatMap(new Function<Throwable, Observable<?>>() {
//                    @Override
//                    public Observable<?> apply(@NonNull Throwable throwable) throws Exception {
//                        if (throwable instanceof TokenInvalidException) {
//                            return refreshTokenWhenTokenInvalid();
//                        } else if (throwable instanceof TokenNotExistException) {
//                            // Token 不存在，执行退出登录的操作。（为了防止多个请求，都出现 Token 不存在的问题，
//                            // 这里需要取消当前所有的网络请求）
//
//                            //mGlobalManager.exitLogin();
//                            return Observable.error(throwable);
//                        }
//                        return Observable.error(throwable);
//                    }
//                });
//            }
//        });
    }

    /**
     * Refresh the token when the current token is invalid.
     *
     * @return Observable
     */
    private Observable<?> refreshTokenWhenTokenInvalid() {
        Log.e("jiejing", "refreshTokenWhenTokenInvalid");
        synchronized (ProxyHandler.class) {
            // Have refreshed the token successfully in the valid time.
            if (new Date().getTime() - tokenChangedTime < REFRESH_TOKEN_VALID_TIME) {
                mIsTokenNeedRefresh = true;
                return Observable.just(true);
            } else {
                return Observable.just(true);
            }
        }
    }

}
